package cn.ray_land.dlprint.data;

import android.support.annotation.NonNull;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static cn.ray_land.dlprint.util.Preconditions.checkNotNull;

/**
 * Created by gw on 2016/8/2.
 */

public class SliceDataRepository implements SliceDataResource{

    private static SliceDataRepository instance;
    private SliceDataResource mDiskDataResource;
    private Map<String, SliceData> mCachedDatas;
    private boolean mCacheIsDirty;

    public static SliceDataRepository getInstance(){
        if(instance == null){
            instance = new SliceDataRepository();
        }
        return instance;
    }

    private SliceDataRepository(){
        mDiskDataResource = DiskSliceDataResource.getInstance();
    }

    @Override
    public void getDatas(@NonNull final LoadDataCallback callback) {
        checkNotNull(callback);

        if (mCachedDatas != null && !mCacheIsDirty) {
            callback.onDataLoaded(new ArrayList<>(mCachedDatas.values()));
            return;
        }

        mDiskDataResource.getDatas(new LoadDataCallback() {
            @Override
            public void onDataLoaded(List<SliceData> datas) {
                refreshCache(datas);
                callback.onDataLoaded(new ArrayList<>(mCachedDatas.values()));
            }

            @Override
            public void onDataNotAvailable() {
                callback.onDataNotAvailable();
            }
        });
    }

    @Override
    public void getData(@NonNull String dataPath, @NonNull GetDataCallback callback) {
        checkNotNull(dataPath);
        checkNotNull(callback);

        SliceData data = getDataWithPath(dataPath);
        if(data!=null){
            callback.onDataLoaded(data);
        }

        mDiskDataResource.getData(dataPath, callback);
    }

    @Override
    public void refreshDatas() {
        mCacheIsDirty = true;
    }

    @Override
    public void deleteAllDatas() {
        mDiskDataResource.deleteAllDatas();
        if(mCachedDatas == null){
            mCachedDatas = new LinkedHashMap<>();
        }
        mCachedDatas.clear();
    }

    @Override
    public void deleteData(@NonNull String dataPath) {
        checkNotNull(dataPath);
        mDiskDataResource.deleteData(dataPath);
        mCachedDatas.remove(dataPath);
    }

    private SliceData getDataWithPath(@NonNull String dataPath) {
        checkNotNull(dataPath);

        if (mCachedDatas == null || mCachedDatas.isEmpty()) {
            return null;
        } else {
            return mCachedDatas.get(dataPath);
        }
    }

    private void refreshCache(List<SliceData> datas) {
        if (mCachedDatas == null) {
            mCachedDatas = new LinkedHashMap<>();
        }
        mCachedDatas.clear();
        for (SliceData data : datas) {
            mCachedDatas.put(data.getSliceFoler().getAbsolutePath(), data);
        }
        mCacheIsDirty = false;
    }
}
